package fr.gdi.android.news.api.greader;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import android.text.TextUtils;

public abstract class AbstractGReaderHelper
{
    
    public static final class Feed 
    {
        public String url;
        public String title;
        
        public String toString() 
        {
            return title;
        }
    }
    
    public static final String _AUTHPARAMS = "GoogleLogin auth=";
    private static final String _GOOGLE_LOGIN_URL = "https://www.google.com/accounts/ClientLogin";
    private static final String _READER_BASE_URL = "http://www.google.com/reader/";
    private static final String _API_URL = _READER_BASE_URL + "api/0/";
    private static final String _TOKEN_URL = _API_URL + "token";
    private static final String _USER_INFO_URL = _API_URL + "user-info";
    private static final String _SUBSCRIPTION_LIST_URL = _API_URL + "subscription/list";
//  private static final String _USER_LABEL = "user/-/label/";
//  private static final String _TAG_LIST_URL = _API_URL + "tag/list";
//  private static final String _EDIT_TAG_URL = _API_URL + "tag/edit";
//  private static final String _RENAME_TAG_URL = _API_URL + "rename-tag";
//  private static final String _DISABLE_TAG_URL = _API_URL + "disable-tag";
//  private static final String _SUBSCRIPTION_URL = _API_URL + "subscription/edit";
    
    /**
     * Returns a Google Authentication Key Requires a Google Username and
     * Password to be sent in the POST headers to
     * http://www.google.com/accounts/ClientLogin
     * 
     * @param GoogleGoogle_Username
     *            Google Username
     * @param Google_Password
     *            Google Password
     * @return Google authorisation token
     * @see getGoogleToken
     */
    public String getGoogleAuthKey(String userName, String password) throws UnsupportedEncodingException, IOException
    {
        Document doc = Jsoup.connect(_GOOGLE_LOGIN_URL)
            .data("accountType", "GOOGLE", 
                  "Email", userName, 
                  "Passwd", password, 
                  "service", "reader", 
                  "source", getApplicationName())
            .userAgent("&lt;your app name&gt;").timeout(4000).post();
        
        // RETRIEVES THE RESPONSE TEXT inc SID and AUTH. We only want the AUTH key.
        String authKey = doc.body().text()
            .substring(doc.body().text().indexOf("Auth="), doc.body().text().length());
        
        authKey = authKey.replace("Auth=", "");
        return authKey;
    }
    
    /**
     * Returns a Google Token Requires a Google Username, Password and Auth key
     * to be sent in the GET to http://www.google.com/reader/api/0/token
     * 
     * @param Google_Username
     *            Google Username
     * @param Google_Password
     *            Google Password
     * @return Google authorisation token
     * @see getGoogleAuthKey
     */
    public String getGoogleToken(String userName, String password) throws UnsupportedEncodingException, IOException
    {
        Document doc = Jsoup.connect(_TOKEN_URL)
             .header("Authorization", _AUTHPARAMS + getGoogleAuthKey(userName, password))
             .userAgent("Scrollable news Widget")
             .timeout(4000).get();
        
        // RETRIEVES THE RESPONSE TOKEN
        String token = doc.body().text();
        return token;
    }
    
    /**
     * Returns Google Reader User Info Requires a Google Username, Password and
     * AUTH key to be sent in the POST to
     * http://www.google.com/reader/api/0/user-info
     * 
     * @param GoogleGoogle_Username
     *            Google Username
     * @param Google_Password
     *            Google Password
     * @return Google Reader User Info
     * @see getGoogleToken
     */
    public String getUserInfo(String _USERNAME, String _PASSWORD) throws UnsupportedEncodingException, IOException
    {
        Document doc = Jsoup.connect(_USER_INFO_URL)
            .header("Authorization", _AUTHPARAMS + getGoogleAuthKey(_USERNAME, _PASSWORD))
            .userAgent("Scrollable news Widget").timeout(4000).get();
        
        // RETRIEVES THE RESPONSE USERINFO
        String userInfo = doc.body().text();
        return userInfo;
    }
    
    public String getUserInfo(String authToken) throws UnsupportedEncodingException, IOException
    {
        Document doc = Jsoup.connect(_USER_INFO_URL)
            .header("Authorization", _AUTHPARAMS + authToken)
            .userAgent("Scrollable news Widget").timeout(4000).get();
    
        // RETRIEVES THE RESPONSE USERINFO
        String userInfo = doc.body().text();
        return userInfo;
    }
    
    /**
     * Returns Google User ID Requires a Google Username and Password to be sent
     * in the POST headers to http://www.google.com/accounts/ClientLogin
     * 
     * USERINFO RETURNED LOOKS LIKE { "userId":"14577161871823252783",
     * "userName":"<username>", "useProfileId":"111618249557856839702",
     * "userEmail":"<email>", "isBloggerUser":true, "signupTimeSec":1159535065 }
     * 
     * @return Google User ID
     * @see getGoogleToken, getGoogleAuthKey
     */
    public String getGoogleUserID(String userName, String password) throws UnsupportedEncodingException, IOException
    {
        
        String userInfo = getUserInfo(userName, password);
        String userId = (String) userInfo.subSequence(11, 31);
        return userId;
    }
    
    public Feed[] getSubscriptionList(String userName, String password) throws UnsupportedEncodingException, IOException
    {
        return getSubscriptionList(getGoogleAuthKey(userName, password));
    }
    
    public Feed[] getSubscriptionList(String authToken) throws UnsupportedEncodingException, IOException
    {
        ArrayList<Feed> list = new ArrayList<Feed>();
        
        Document doc = null;
        
        doc = Jsoup.connect(_SUBSCRIPTION_LIST_URL)
                .header("Authorization", _AUTHPARAMS + authToken)
                .userAgent(getApplicationName()).timeout(5000).get();
        
        
        Elements objects = doc.select("object");
        
        for (Element obj: objects)
        {
            Elements links = obj.select("string");
            
            String title = null, url = null;

            for (Element link : links)
            {
                String tagAttrib = link.attr("name");
                String tagText = link.text();
                if ( TextUtils.equals(tagAttrib, "id") )
                {
                    url = tagText.substring(5);
                }
                else if ( TextUtils.equals(tagAttrib, "title") )
                {
                    title = tagText;
                }
                else 
                {
                    continue;
                }  
            }
            
            if ( !TextUtils.isEmpty(url) && !TextUtils.isEmpty(title) ) 
            {
                Feed feed = new Feed();
                feed.title = title;
                feed.url = url;
                list.add(feed);
            }
        }
        
        return list.toArray(new Feed[list.size()]);
    }

    public String getAtomReadingList(String userName, String password) throws Exception
    {
        Document doc = Jsoup.connect("http://www.google.com/reader/atom/user/-/" +
                 "state/com.google/reading-list").header("Authorization", _AUTHPARAMS + getGoogleAuthKey(userName, password))
                .userAgent("Scrollable news widget").timeout(5000).get();
        
        return doc.toString();
    }
  
    
    public String getAuthenticationToken(String login, String password) throws UnsupportedEncodingException, IOException 
    {
        return _AUTHPARAMS + getGoogleAuthKey(login, password);
    }
    
    protected abstract String getApplicationName();
  
}
